Vue Lifecycle

Vue 實體在被創建時會經過一系列初始化的步驟,如數據監聽、編譯模板、掛載實體、綁定資料等。與此同時 Vue 也提供了讓使用者能在特定階段自行客製化程式碼的方法,這些方法就稱為 Lifecycle Hook。

生命週期掛鉤

創建階段

  • beforeCreate:實體建構前。
  • Created:實體建構後調用,此時 Vue 實體內除 $el 外皆已配置(可取得並處理)。

掛載階段

  • beforeMount:渲染至 template 之前。
  • mounted:$el 配置與渲染。

    此鉤子無法保證所有的子組件也都一起被掛載。如果希望等到整個視圖都渲染完畢,可以在 mounted 內部使用 vm.$nextTick

    1
    2
    3
    4
    5
    mounted: function () {
    this.$nextTick(function () {
    // 視圖渲染完畢後執行
    })
    }

資料更新階段

  • beforeUpdate:資料變化後,視圖改變前。
  • updated:視圖更新後調用。
    多數情況下應避免在此期間更改狀態。如需改變相應狀態,通常最好使用計算屬性或是 watcher。

    此鉤子無法保證所有的子組件也都一起被重繪。如果希望等到整個視圖都重繪完畢,可以在 updated 裏使用 vm.$nextTick

    1
    2
    3
    4
    5
    updated: function () {
    this.$nextTick(function () {
    // 視圖渲染完畢後執行
    })
    }

刪除階段

  • beforeDestroy:實體銷毀前調用。
  • destroyed:實體銷毀後調用。

保存/緩存狀態

  • activated:keep-alive 觸發時調用。
  • deactivated:keep-alive 停用時調用。

※ 若有設定 <keep-alive>,則只會有 activated Hook 與 deactivated Hook,而不觸發 destroyed Hook。

錯誤處理

  • errorCaptured:捕獲子孫組件的錯誤時調用。

    此鉤子會收到三個參數:錯誤對象、發生錯誤的組件實體以及一個包含錯誤來源信息的字符串。並返回 false 以阻止該錯誤繼續向上傳播。


範例

1
2
3
4
5
<div id="app">
{{ Lifecycle }}
<button v-on:click="Lifecycle++">add</button>
<button v-on:click="$destroy()">Destroy instance</button>
</div>

初始化時

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var vm = new Vue({
el: '#app',
data: {
Lifecycle: 1
},
// 實體被 constructor 建立前
beforeCreate() {
console.log('beforeCreate');
console.log(`this.Lifecycle: ${this.Lifecycle}`); // undefined
console.log(`this.$el: ${this.$el}`); // undefined
console.log();
},
// 實體被 constructor 建立後,在這裡完成 data binding
created() {
console.log('created');
console.log(`this.Lifecycle: ${this.Lifecycle}`); // 1
console.log(`this.$el: ${this.$el}`); // undefined
console.log();
},
// 綁定 DOM 之前
beforeMount() {
console.log('beforeMount');
console.log(this.$el.outerHTML);
// <div id='app'>
// {{ Lifecycle }}
// <button v-on:click='Lifecycle++'>add</button>
// <button v-on:click='$destroy()'>Destroy instance</button>
// </div>
console.log();
},
// 綁定 DOM 之後
mounted() {
console.log('mounted');
console.log(this.$el.outerHTML);
// <div id='app'>
// 1
// <button>add</button> <button>Destroy instance</button></div>
console.log();
},
});

按下 add

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var vm = new Vue({
el: '#app',
data: {
Lifecycle: 1
},
// 資料更新,但尚未更新 DOM
beforeUpdate() {
console.log('beforeUpdate');
console.log(`this.Lifecycle: ${this.Lifecycle}`); // 2
console.log(this.$el.outerHTML);
// <div id='app'>
// 1
// <button>add</button> <button>Destroy instance</button></div>
console.log();
},
// 資料更新,並更新 DOM
updated() {
console.log('updated');
console.log(`this.Lifecycle: ${this.Lifecycle}`); // 2
console.log(this.$el.outerHTML);
// <div id='app'>
// 2
// <button>add</button> <button>Destroy instance</button></div>
console.log();
},
});

按下 Destroy instance

1
2
console.log(`this.Lifecycle: ${this.Lifecycle}`); // undefined
console.log(`this.$el: ${this.$el}`); // undefined

生命週期圖示

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×